package com.duoec.dw.lineage.service.analyser.from;

import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.duoec.dw.lineage.dto.MultiTableLineageDto;
import com.duoec.dw.lineage.dto.TableFieldDependencyDto;
import com.duoec.dw.lineage.dto.TableLineageDto;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.LinkedHashSet;

/**
 * @author xuwenzhen
 */
@Service
public class JoinTableSourceAnalyser extends BaseTableSourceAnalyser<SQLJoinTableSource> {
    /**
     * 获取当前类处理的类型
     *
     * @return SQLTableSource子类类型
     */
    @Override
    public Class<SQLJoinTableSource> getTableSourceType() {
        return SQLJoinTableSource.class;
    }

    /**
     * 解析 from
     *
     * @param tableSource         需要解析的from
     * @param withAsTableLineages with-in
     * @return 当前select脚本的血缘关系
     */
    @Override
    public MultiTableLineageDto analyse(SQLJoinTableSource tableSource, MultiTableLineageDto withAsTableLineages) {
        MultiTableLineageDto fromLineages = new MultiTableLineageDto();

        analyseJoinTableSource(fromLineages, tableSource.getLeft(), withAsTableLineages);
        analyseJoinTableSource(fromLineages, tableSource.getRight(), withAsTableLineages);

        //where
        SQLExpr condition = tableSource.getCondition();
        LinkedHashSet<TableFieldDependencyDto> whereDependencies = hiveAnalyser.analyseWhere(fromLineages, condition);
        if (whereDependencies != null) {
            String alias = tableSource.getRight().getAlias();
            TableLineageDto tableLineage;
            if (!StringUtils.isEmpty(alias)) {
                //设置了别名，从别名中取出对应的表
                tableLineage = fromLineages.getTable(alias);
            } else {
                //没有设置别名
                tableLineage = fromLineages.getFirst();
            }
            LinkedHashSet<TableFieldDependencyDto> dependencies = tableLineage.getDependencies();
            if (dependencies == null) {
                dependencies = new LinkedHashSet<>();
                tableLineage.setDependencies(dependencies);
            }
            dependencies.addAll(whereDependencies);
        }
        return fromLineages;
    }

    private void analyseJoinTableSource(MultiTableLineageDto dto, SQLTableSource tableSource, MultiTableLineageDto withAsTableLineages) {
        MultiTableLineageDto multiTableLineageDto = hiveAnalyser.analyseFrom(tableSource, withAsTableLineages);
        if (multiTableLineageDto.size() == 1) {
            String alias = tableSource.getAlias();
            if (!StringUtils.isEmpty(alias)) {
                multiTableLineageDto.setAlias(alias);
            }
        }

        dto.add(multiTableLineageDto);
    }
}
